using ClosedXML.Excel;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PHMEE.EnergyEfficiency;
using Volo.Abp;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Guids;
using Volo.Abp.Uow;

namespace PHMEE.ConsoleTools.EnergyEfficiency;

public class CiiReductionFactorImporter
{
    public const string CommandName = "import-cii-factor";

    private IUnitOfWorkManager _unitOfWorkManager;
    private IRepository<CiiReductionFactor, Guid> _ciiReductionFactorRepository;
    private ILogger<CiiReductionFactorImporter> _logger;
    private IGuidGenerator _guidGenerator;

    public async Task RunCommandAsync(string[] commandParts, IServiceProvider serviceProvider)
    {
        if (commandParts.Length != 2)
        {
            throw new UserFriendlyException("请提供 CII Reduction Factor 的 Excel 文件路径");
        }

        var filePath = commandParts[1];

        if (string.IsNullOrWhiteSpace(filePath))
        {
            throw new UserFriendlyException("Excel 文件路径不能为空");
        }

        _unitOfWorkManager = serviceProvider.GetRequiredService<IUnitOfWorkManager>();
        _ciiReductionFactorRepository = serviceProvider.GetRequiredService<IRepository<CiiReductionFactor, Guid>>();
        _logger = serviceProvider.GetRequiredService<ILogger<CiiReductionFactorImporter>>();
        _guidGenerator = serviceProvider.GetRequiredService<IGuidGenerator>();

        await ImportAsync(filePath);
    }

    private async Task ImportAsync(string filePath)
    {
        await using var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
        using var workbook = new XLWorkbook(fileStream);

        var worksheet = workbook.Worksheet(1);

        var rows = worksheet.RangeUsed()?.RowsUsed().Skip(1) ?? throw new UserFriendlyException("Excel 文件中没有数据");

        // 需要 Unit of work
        using var uow = _unitOfWorkManager.Begin();

        try
        {
            List<CiiReductionFactor> factors = [];

            foreach (var row in rows)
            {
                int year = row.Cell("A").GetValue<int>();
                float z = row.Cell("B").GetValue<float>();

                // 检查 year 是否已经存在
                var existingFactor = await _ciiReductionFactorRepository.FirstOrDefaultAsync(x => x.Year == year);
                if (existingFactor != null)
                {
                    _logger.LogInformation("年份 {0} 的 CII 降低系数已经存在，跳过", year);
                    continue;
                }

                var factor = new CiiReductionFactor(_guidGenerator.Create(), year, z);
                factors.Add(factor);
            }

            await _ciiReductionFactorRepository.InsertManyAsync(factors, autoSave: true);
            await uow.CompleteAsync();

            _logger.LogInformation("CII Reduction Factor 导入成功，共导入 {0} 条数据", factors.Count);
        }
        catch (Exception ex)
        {
            await uow.RollbackAsync();
            _logger.LogError(ex, "导入 CII Reduction Factor 时发生错误");
        }
    }
}